package com.zmovie.front.controller;

import com.alibaba.fastjson.JSON;
import com.zmovie.common.error.BusinessException;
import com.zmovie.common.error.EnumBusinessError;
import com.zmovie.common.utils.FileUtils;
import com.zmovie.framework.domain.*;
import com.zmovie.framework.service.*;
import com.zmovie.front.constant.Constants;
import com.zmovie.front.controller.vo.CinemaVO;
import com.zmovie.front.controller.vo.MovieVO;
import com.zmovie.front.controller.vo.SessionVO;
import com.zmovie.front.util.MoviePathUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 挚爱之夕
 * @version 1.0
 * @implSpec com.zmovie.front.controller
 * @since 2023-12-19 11:37
 */
@Controller
@RequestMapping("/cinemaInfo")
@Api(tags = "影院详情")
public class CinemaInfoController {
    @Autowired
    private CinemaService cinemaService;
    @Autowired
    private SessionService sessionService;
    @Autowired
    private CinemaAreaService cinemaAreaService;
    @Autowired
    private MovieService movieService;
    @Autowired
    private MovieRuntimeService movieRuntimeService;
    @Autowired
    private HallService hallService;
    @Autowired
    private MovieRateService movieRateService;
    @Autowired
    private MovieToTypeService movieToTypeService;
    @Autowired
    private ActorMovieService actorMovieService;

    @GetMapping("/{id}")
    @ApiOperation("影院详情页面")
    public String index(Model model, @PathVariable("id") Integer id) {
        //影院信息
        Cinema cinema = cinemaService.getById(id);
        model.addAttribute(Constants.CINEMA_KEY, convert(cinema));
        //该影院下播放的电影
        List<Integer> movieIds = sessionService.listMovieIdsByCinemaId(cinema.getId());
        List<Movie> movies;
        if(movieIds.size() > 0){
            movies = movieService.listByIds(movieIds);
            model.addAttribute(Constants.MOVIES_KEY, convert(movies));
            //选中第一个电影
            int movieId = movies.get(0).getId();
            model.addAttribute(Constants.SHOW_MOVIE_ID, movieId);
            model.addAttribute(Constants.SHOW_MOVIE_KEY, convert(movies.get(0)));
            //获取日期列表
            List<Date> dates = sessionService.listDateByCinemaIdAndMovieId(cinema.getId(), movieId);
            model.addAttribute(Constants.DATES_KEY, dates);
            if(dates.size() > 0){
                //选中第一个日期
                Date date = dates.get(0);
                model.addAttribute(Constants.SELECTED_DATE_KEY, date);
                //查询该日期下的场次
                Session session = new Session();
                session.setCinemaId(cinema.getId());
                session.setMovieId(movieId);
                session.setDate(date);
                List<Session> sessions = sessionService.listCondition(session);
                model.addAttribute(Constants.SESSIONS_KEY, convertSession(sessions));
            }
        }else{
            movies = new ArrayList<>();
            model.addAttribute(Constants.MOVIES_KEY, convert(movies));
            model.addAttribute(Constants.SHOW_MOVIE_ID, 0);
            MovieVO movieVO = new MovieVO();
            movieVO.setMovieRate(new MovieRate());
            model.addAttribute(Constants.SHOW_MOVIE_KEY, movieVO);
        }
        return "cinema_info";
    }
    @PostMapping
    @ApiOperation("场次页面片段")
    public String showSession(Model model, Session session) throws BusinessException {
        Integer cinemaId = session.getCinemaId();
        Integer movieId = session.getMovieId();
        //参数检查
        if(cinemaId == null || movieId == null){
            throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR);
        }
        model.addAttribute(Constants.SHOW_MOVIE_ID, movieId);
        model.addAttribute(Constants.SHOW_MOVIE_KEY, convert(movieService.getById(movieId)));
        //获取日期列表
        List<Date> dates = sessionService.listDateByCinemaIdAndMovieId(cinemaId, movieId);
        model.addAttribute(Constants.DATES_KEY, dates);
        Date date = session.getDate();
        //选中日期
        if(dates.size() > 0){
            //前端未传选中第一个
            model.addAttribute(Constants.SELECTED_DATE_KEY, date == null ? dates.get(0) : date);
            //查询该日期下的场次
            if(session.getDate() == null){
                session.setDate(dates.get(0));
            }
            List<Session> sessions = sessionService.listCondition(session);
            model.addAttribute(Constants.SESSIONS_KEY, convertSession(sessions));
        }
        return "cinema_info :: sessionList";
    }

    private List<SessionVO> convertSession(List<Session> sessionList){
        return sessionList.stream().map(this::convert).collect(Collectors.toList());
    }
    private SessionVO convert(Session session){
        SessionVO sessionVO = new SessionVO();
        BeanUtils.copyProperties(session, sessionVO);
        //播放时段
        MovieRuntime runtime = movieRuntimeService.getById(sessionVO.getMovieRuntimeId());
        sessionVO.setMovieRuntime(runtime);
        //影厅
        Hall hall = hallService.getById(session.getHallId());
        sessionVO.setHall(hall);
        return sessionVO;
    }
    private MovieVO convert(Movie movie) {
        //处理文件路径
        MovieVO movieVO = MoviePathUtil.dealMovieFilePath(movie);
        //评分
        MovieRate movieRate = movieRateService.getByMovieId(movie.getId());
        movieVO.setMovieRate(movieRate);
        //类型
        List<MovieType> types = movieToTypeService.listTypeByMovieId(movie.getId());
        movieVO.setTypes(types);
        //主演
        List<Actor> actors = actorMovieService.listProtagonist(movie.getId());
        movieVO.setActors(actors);
        return movieVO;
    }

    private List<MovieVO> convert(List<Movie> movies) {
        return movies.stream().map(this::convert).collect(Collectors.toList());
    }

    private CinemaVO convert(Cinema cinema) {
        CinemaVO cinemaVO = new CinemaVO();
        BeanUtils.copyProperties(cinema, cinemaVO);
        //图片
        String posterJsonList = cinema.getPicture();
        List<String> posterList = JSON.parseArray(posterJsonList, String.class);
        if(posterList.size() > 0)
            cinemaVO.setPicture(FileUtils.dealFilePath(posterList.get(0)));
        //影院地址
        CinemaArea area = cinemaAreaService.getById(cinema.getAreaId());
        cinemaVO.setCinemaArea(area);
        return cinemaVO;
    }
}
